import G6 from '@antv/g6'
// import { treedata } from './treedata'
// import Vue from 'vue'
// 折叠图标函数
const COLLAPSE_ICON = function COLLAPSE_ICON (x, y, r) {
  return [
    ['M', x - r, y - r],
    ['a', r, r, 0, 1, 0, r * 2, 0],
    ['a', r, r, 0, 1, 0, -r * 2, 0],
    ['M', x + 2 - r, y - r],
    ['L', x + r - 2, y - r]
  ]
}
// 展开图标函数
const EXPAND_ICON = function EXPAND_ICON (x, y, r) {
  return [
    ['M', x - r, y - r],
    ['a', r, r, 0, 1, 0, r * 2, 0],
    ['a', r, r, 0, 1, 0, -r * 2, 0],
    ['M', x + 2 - r, y - r],
    ['L', x + r - 2, y - r],
    ['M', x, y - 2 * r + 2],
    ['L', x, y - 2]
  ]
}

// 深度优先遍历树数据 从根到子
// G6.Util.traverseTree(treedata, (d) => {
//   d.leftIcon = {
//     style: {
//       fill: '#e6fffb',
//       stroke: '#e6fffb'
//     },
//     img: 'https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*Q_FQT6nwEC8AAAAAAAAAAABkARQnAQ'
//   }
//   return true
// })

// 自定义元素 G6.registerX
// 自定义节点-当内置节点不满足需求时，可以通过 G6.registerNode(nodeName, options, extendedNodeName) 方法自定义节点。
// nodeName 自定义节点的名称 唯一性  必须
// options,自定义节点的配置项是个对象 必须
// extendedNodeName 可以基于内置节点自定义节点
G6.registerNode(
  'icon-node',
  {
    options: {
      size: [60, 20], // 宽高
      stroke: '#91d5ff', // 变颜色
      fill: '#91d5ff'// 填充色
    },
    // draw是绘制后的附加操作-节点的配置项  图形分组，节点中图形对象的容器
    draw (cfg, group) {
      // 获取节点的配置
      const styles = this.getShapeStyle(cfg)
      // 解构赋值
      const { labelCfg = {} } = cfg

      const w = styles.width
      const h = styles.height
      // 向分组中添加新的图形 图形 配置 rect矩形 xy 代表左上角坐标 w h是宽高
      const keyShape = group.addShape('rect', {
        attrs: {
          ...styles,
          x: -w / 2,
          y: -h / 2
        }
      })

      console.log('cfg.leftIcon', cfg.leftIcon)
      // 如果有左侧图标 向分组中添加新的图形的配置
      if (cfg.leftIcon) {
        const { style, img } = cfg.leftIcon
        group.addShape('rect', {
          attrs: {
            x: 1 - w / 2,
            y: 1 - h / 2,
            width: 38,
            height: styles.height - 2,
            fill: '#8c8c8c',
            ...style
          }
        })

        group.addShape('image', {
          attrs: {
            x: 8 - w / 2,
            y: 8 - h / 2,
            width: 24,
            height: 24,
            img:
              img ||
              'https://g.alicdn.com/cm-design/arms-trace/1.0.155/styles/armsTrace/images/TAIR.png'
          },
          name: 'image-shape'
        })
      }

      // 如果不需要动态增加或删除元素，则不需要 add 这两个 marker
      group.addShape('marker', {
        attrs: {
          x: 40 - w / 2,
          y: 52 - h / 2,
          r: 6,
          stroke: '#73d13d',
          cursor: 'pointer',
          symbol: EXPAND_ICON
        },
        name: 'add-item'
      })

      group.addShape('marker', {
        attrs: {
          x: 80 - w / 2,
          y: 52 - h / 2,
          r: 6,
          stroke: '#ff4d4f',
          cursor: 'pointer',
          symbol: COLLAPSE_ICON
        },
        name: 'remove-item'
      })
      // 文本文字的配置
      if (cfg.label) {
        group.addShape('text', {
          attrs: {
            ...labelCfg.style,
            text: cfg.label,
            x: 50 - w / 2,
            y: 25 - h / 2
          }
        })
      }

      return keyShape
    },
    // 更新节点后的操作，一般同 afterDraw 配合使用
    update: undefined
  },
  'rect'
)

// 自定义边
// 参数1 自定义边的名称 参数2 自定义边时的配置项(对象) 参数3 自定义边时可基于内置边进行定义(选填)
G6.registerEdge('flow-line', {
// 绘制后的附加操作
  draw (cfg, group) {
    // 边两端与起始节点和结束节点的交点；
    const startPoint = cfg.startPoint
    const endPoint = cfg.endPoint
    // 边的配置
    const { style } = cfg
    const shape = group.addShape('path', {
      attrs: {
        stroke: style.stroke, // 边框的样式
        endArrow: style.endArrow, // 结束箭头
        // 路径
        path: [
          ['M', startPoint.x, startPoint.y],
          ['L', startPoint.x, (startPoint.y + endPoint.y) / 2],
          ['L', endPoint.x, (startPoint.y + endPoint.y) / 2],
          ['L', endPoint.x, endPoint.y]
        ]
      }
    })

    return shape
  }
})

// 默认的鼠标悬停会加粗,边框颜色改变
const defaultStateStyles = {
  hover: {
    stroke: '#1890ff',
    lineWidth: 2
  }
}

// 默认节点的颜色 边 圆角的配置
const defaultNodeStyle = {
  fill: '#91d5ff',
  stroke: '#40a9ff',
  radius: 5
}

// 默认边的颜色 末尾箭头
const defaultEdgeStyle = {
  stroke: '#91d5ff',
  endArrow: {
    path: 'M 0,0 L 12, 6 L 9,0 L 12, -6 Z',
    fill: '#91d5ff',
    d: -20
  }
}

// 默认布局
// compactBox 紧凑树布局
// 从根节点开始，同一深度的节点在同一层，并且布局时会将节点大小考虑进去。
const defaultLayout = {
  type: 'compactBox', // 布局类型树
  direction: 'TB', // TB 根节点在上，往下布局
  getId: function getId (d) { // 节点 id 的回调函数
    return d.id
  },
  getHeight: function getHeight () { // 节点高度的回调函数
    return 16
  },
  getWidth: function getWidth () { // 节点宽度的回调函数
    return 16
  },
  getVGap: function getVGap () { // 节点纵向间距的回调函数
    return 40
  },
  getHGap: function getHGap () { // 节点横向间距的回调函数
    return 70
  }
}

// 文本配置项
const defaultLabelCfg = {
  style: {
    fill: '#000',
    fontSize: 12
  }
}

// 获取容器
const container = document.getElementById('container')
// 获取容器的宽高
const width = container.scrollWidth
const height = container.scrollHeight || 500

// 实例化 Grid 插件-小地图
const minimap = new G6.Minimap({
  size: [150, 100]
})
// 实例化 Menu 插件-右击
const menu = new G6.Menu({
  offsetX: 6,
  offsetY: 10,
  itemTypes: ['node'],
  getContent (e) {
    const outDiv = document.createElement('div')
    outDiv.style.width = '180px'
    outDiv.innerHTML = `<ul>
        <li>测试01</li>
        <li>测试01</li>
        <li>测试01</li>
        <li>测试01</li>
        <li>测试01</li>
      </ul>`
    return outDiv
  }
})

// Graph 是 G6 图表的载体-实例化
const graph = new G6.TreeGraph({
  container: 'container', // 图的 DOM 容器
  width,
  height,
  linkCenter: true, // 指定边是否连入节点的中心
  plugins: [minimap, menu], // 插件
  modes: { // 交互模式
    // default 模式中包含点击选中节点行为和拖拽画布行为;
    default: ['drag-canvas', 'zoom-canvas']
  },
  // 默认状态下节点的配置
  defaultNode: {
    type: 'icon-node',
    size: [120, 40],
    style: defaultNodeStyle,
    labelCfg: defaultLabelCfg
  },
  // 默认状态下边的配置，
  defaultEdge: {
    type: 'flow-line',
    style: defaultEdgeStyle
  },
  // 各个状态下节点的样式-，例如 hover、selected，3.1 版本新增。
  nodeStateStyles: defaultStateStyles,

  // 各个状态下边的样式-，例如 hover、selected，3.1 版本新增。
  edgeStateStyles: defaultStateStyles,
  // 布局配置项
  layout: defaultLayout
})

// 初始化的图数据，是一个包括 nodes 数组和 edges 数组的对象

// 深度优先遍历树数据 从根到子
// G6.Util.traverseTree(treedata, (d) => {
//   d.leftIcon = {
//     style: {
//       fill: '#e6fffb',
//       stroke: '#e6fffb'
//     },
//     img: 'https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*Q_FQT6nwEC8AAAAAAAAAAABkARQnAQ'
//   }
//   return true
// })
// graph.data(treedata)

// // 根据提供的数据渲染视图。
// graph.render()
// // 让画布内容适应视口。
// graph.fitView()
// // 改变视口的缩放比例，在当前画布比例下缩放，是相对比例。
// graph.zoom(1)

// 鼠标移入元素范围内触发
// graph.on('node:mouseenter', (evt) => {
//   const { item } = evt
//   graph.setItemState(item, 'hover', true)
// })
// // 鼠标移出目标元素后触发
// graph.on('node:mouseleave', (evt) => {
//   const { item } = evt// item表示触发元素
//   graph.setItemState(item, 'hover', false)
// })

// // 单击鼠标左键或者按下回车键时触发
// graph.on('node:click', (evt) => {
// // item: 事件的触发元素（节点/边/ Combo）
// // target: 事件的触发图形 Shape 或画布对象
//   const { item, target } = evt
//   // type: 事件类型
//   // name: 事件名称
//   const targetType = target.get('type')
//   const name = target.get('name')

//   // 增加元素
//   if (targetType === 'marker') {
//     const model = item.getModel()
//     if (name === 'add-item') {
//       if (!model.children) {
//         model.children = []
//       }
//       const id = `n-${Math.random()}`
//       model.children.push({
//         id,
//         label: id.substr(0, 8),
//         leftIcon: {
//           style: {
//             fill: '#e6fffb',
//             stroke: '#e6fffb'
//           },
//           img:
//             'https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*Q_FQT6nwEC8AAAAAAAAAAABkARQnAQ'
//         }
//       })
//       graph.updateChild(model, model.id)
//     } else if (name === 'remove-item') {
//       // // 移除节点
//       graph.removeChild(model.id)
//     }
//   }
// })

if (typeof window !== 'undefined') {
  window.onresize = () => {
    if (!graph || graph.get('destroyed')) return
    if (!container || !container.scrollWidth || !container.scrollHeight) return
    graph.changeSize(container.scrollWidth, container.scrollHeight)
  }
}

export default graph
